package com.road.yishi.mina;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.road.yishi.BaseServer;
import com.road.yishi.proto.PBMessage;

/**
 * 管理网关服务器的MINA连接
 */
public class GatewayLinkedSet {

	
	private static final Logger LOGGER = LoggerFactory.getLogger(GatewayLinkedSet.class);
	
	private static Map<Integer, LinkedClient> clients = new ConcurrentHashMap<Integer, LinkedClient>();
	private static Map<String, LinkedClient> crossClients = new ConcurrentHashMap<String, LinkedClient>();
	private static Map<String, List<LinkedClient>> gatewayClients = new ConcurrentHashMap<String, List<LinkedClient>>();
	private static int gatewayCount = 0; // 网关数量
	private static int clientIndex = 0;

	private GatewayLinkedSet() {

	}

	public static void init(int count) {
		gatewayCount = count;
	}

	private static String genKey(LinkedClient client) {
		return client.getName() + "_" + client.getId() + "_" + client.getIndex();
	}

	/**
	 * 添加到集合管理器
	 * 
	 * @param linkedClient
	 * @return
	 */
	public static LinkedClient addLinkedClient(LinkedClient client) {
		LOGGER.info("连接到服务器, linkedclient : " + client.toString());
/*		if (BaseServer.isCross) {
			crossClients.put(genKey(client), client);
			addGatewayClient(client);
		}*/
		return clients.put(client.getId(), client);
	}

	/**
	 * 删除指定的连接
	 * 
	 * @param linkedClient
	 * @return
	 */
	public static LinkedClient removeLinkedClient(IoSession session) {
		LinkedClient client = getLinkedClient(session);
		if (client == null) {
			return null;
		}
/*		if (BaseServer.isCross) {
			crossClients.remove((genKey(client)));
			removeGatewayClient(client);
		}*/
		return clients.remove(client.getId());
	}

	public static LinkedClient getLinkedClient(IoSession session) {
		LinkedClient client = (LinkedClient) session.getAttribute(LinkedClient.KEY_CLIENT);
		return client;
	}

	/**
	 * 根据用户ID计算发送到固定网关
	 * 
	 * @param userId
	 * @param packet
	 */
	public static void send(int userId, PBMessage packet) {
		LinkedClient client = null;
		if (userId <= 0) {
			sendSingle(packet);
		} else {
			int idx = userId % gatewayCount;
			client = clients.get(idx);

			if (client != null) {
				client.send(userId, packet);
			} else {
				LOGGER.error("Can not found gateway connection , userId = " + userId + " code : " + packet.getCode() + " . packet forward failed.");
			}
		}
	}

	private static void sendSingle(PBMessage packet) {
		for (Entry<Integer, LinkedClient> linkedEntry : clients.entrySet()) {
			LinkedClient linked = linkedEntry.getValue();
			if (linked != null) {
				linked.send(-1, packet);
				break;
			}
		}
	}

	/**
	 * 发送数据包
	 */
	public static void send(PBMessage packet) {
		send(packet.getPlayerId(), packet);
	}

	/**
	 * 发送到所有网关连接
	 * 
	 * @param packet
	 */
	public static void sendAll(PBMessage packet) {
		for (Entry<Integer, LinkedClient> linkedEntry : clients.entrySet()) {
			LinkedClient linked = linkedEntry.getValue();
			if (linked != null) {
				linked.send(-1, packet);
			}
		}
	}

	public static void sendCrossAll(PBMessage packet) {
		for (Entry<String, LinkedClient> linkedEntry : crossClients.entrySet()) {
			LinkedClient linked = linkedEntry.getValue();
			if (linked != null) {
				linked.send(-1, packet);
			}
		}
	}

	private static void addGatewayClient(LinkedClient client) {
		if (!gatewayClients.containsKey(client.getName())) {
			gatewayClients.put(client.getName(), new ArrayList<LinkedClient>());
		}
		List<LinkedClient> list = gatewayClients.get(client.getName());
		list.add(client);
	}

	private static void removeGatewayClient(LinkedClient client) {
		if (!gatewayClients.containsKey(client.getName())) {
			return;
		}
		List<LinkedClient> list = gatewayClients.get(client.getName());
		list.remove(client);
	}

	public static LinkedClient getGatewayClient(String name) {
		List<LinkedClient> clientList = gatewayClients.get(name);
		if (clientList == null || clientList.isEmpty()) {
			return null;
		}
		LinkedClient client = clientList.get(clientIndex % clientList.size());
		clientIndex = ((clientIndex + 1) & 0xfff);
		return client;
	}
}
